package dom.xpath.query;

import dom.xpath.core.Progress;
import dom.xpath.core.Prop;
import dom.xpath.data.Nodes;
import dom.xpath.data.Result;
import dom.xpath.util.TokenBuilder;
import static dom.xpath.core.proc.ProcText.*;

/**
 * This abstract query expression provides the architecture
 * for a compiled query.
 *
 * @author Workgroup DBIS, University of Konstanz 2005-07, ISC License
 * @author Christian Gruen
 */
public abstract class QueryContext extends Progress {
  /** String container for query background information. */
  protected final TokenBuilder info = new TokenBuilder();
  /** Optimization flag. */
  protected boolean firstOpt = true;
  /** Evaluation flag. */
  protected boolean firstEval = true;

  /**
   * Optimizes the expression.
   * @param nodes node context
   * @throws EvalException evaluation exception
   */
  public abstract void compile(Nodes nodes) throws EvalException;
  
  /**
   * Evaluates the expression with the specified context set.
   * @param nodes initial context set
   * @return resulting value
   * @throws EvalException evaluation exception
   */
  public abstract Result eval(Nodes nodes) throws EvalException;

  /**
   * Adds some optimization info.
   * @param string evaluation info
   * @param ext text text extensions
   */
  public final void compInfo(final String string, final Object... ext) {
    if(Prop.allInfo) {
      if(!firstOpt) info.add(QUERYSEP);
      firstOpt = false;
      info.add(string, ext);
      info.add(NL);
    }
  }

  /**
   * Adds some evaluation info.
   * @param string evaluation info
   * @param ext text text extensions
   */
  public final void evalInfo(final String string, final Object... ext) {
    if(Prop.allInfo) {
      if(firstEval) {
        //if(info.size != 0) info.add(NL);
        info.add(NL);
        info.add(QUERYEVAL);
        info.add(NL);
        firstEval = false;
      }
      info.add(QUERYSEP);
      info.add(string, ext);
      info.add(NL);
    }
  }

  /**
   * Returns query background information.
   * @return warning
   */
  public final String info() {
    return info.toString();
  }

  @Override
  public final String head() {
    return QUERYINFO;
  }

  @Override
  public final String det() {
    return QUERYINFO;
  }

  @Override
  public final double prog() {
    return 0;
  }
}
